// 判断是否数字
const isNumber = (n) => {
    return /^-?\d+(\.\d+)?$/.test(n+'') || /[+-]?\d*\.?\d+e[+-]?\d+/i.test(n+'')
}
// 判断几位小数
const floatLength = (n) => {
    let va = n.split('.')[1]
    return va ? va.length: 0
}
// 将小数变成整倍整数
const toInt = (n, digit) => {
    let sn = (n + '').split('.')
    if (sn[1]) {
        return sn[0] + sn[1].padEnd(digit, '0')
    } else {
        return sn[0]+''.padEnd(digit, '0')
    }
}
// 处理科学计数法
const numberToString = (num) => {
    let [val, e] = (num + '').toLowerCase().split('e')
    e = parseFloat(e)
    if (e && e > 0) {
        let [star, end] = val.split('.')
        return star + end.padEnd(e, '0')
    } else if (e && e < 0) {
        let [integer, decimal] = (val + '').split('.')
        if (integer.length > Math.abs(e)) {
            let le = integer.length + e
            return insertChar(integer, le, '.') + (decimal||'')
        } else {
            let newNum =  integer.padStart(Math.abs(e),'0') + (decimal || '')
            return newNum = '0.' + newNum
        } 
    } else {
        return val
    }
}
// 函数共用部分
const common = (n, m) => {
    if(isNumber(n) && isNumber(m)) {
        n = numberToString(n)
        m = numberToString(m)
        let digit = Math.max(floatLength(n), floatLength(m))
        return({ digit, xn: toInt(n, digit), xm: toInt(m, digit) })
    } else {
        throw new Error("入参必须都为数字")
    }  
}
// 指定位置加入自定义字符
const insertChar = (str, index, char) => {
    return str.replace(/./g, (match, i) => {
        if (i === index) {
            return char + match
        } else {
            return match
        }
    })
}
// 整理返回的数字
const handleStr = (str) => {
    if (str === '0') return '0'
    str = str.replace(/^0+/, '')
    str = str.includes('.') ? str.replace(/(\.\d*?[1-9])?0+$/, '$1') : str
    str = str.replace(/\.$/, '')
    str = str.indexOf('.') === 0 ? ('0' + str) : str
    str = str.indexOf('-.') === 0 ? ('-0.' + str.split('-.')[1]): str
    return str
}
// 两个数的和 支持小数相加
export const add = (n, m) => {
    let {digit, xn, xm} = common(n, m)
    let sum = numberToString(BigInt(xn) + BigInt(xm)).padStart(digit, '0')
    return  handleStr(insertChar(sum, sum.length - digit, '.'))
}
// 两个数的差 支持小数相加
export const subtract = (n, m) => {
    let {digit, xn, xm} = common(n, m)
    let sum = numberToString(BigInt(xn) - BigInt(xm)).padStart(digit, '0')
    return  handleStr(insertChar(sum, sum.length - digit, '.'))
}
// 两个数的积 支持小数相加
export const multiply = (n, m) => {
    let {digit, xn, xm} = common(n, m)
    let sum = numberToString(BigInt(xn) * BigInt(xm)).padStart(digit*2, '0')
    return  handleStr(insertChar(sum, sum.length - (digit*2), '.'))
}
// 两个数的倍数 支持小数相加
export const divide = (n, m) => {
    let { xn, xm} = common(n, m)
    if((xn + '').length > 307 || (xm + '').length > 307) {
        xn = BigInt(xn)
        xm = BigInt(xm)
    }
    return handleStr(numberToString(xn / xm))
}